﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;


namespace Project1
{
    public class Rat
    {
        #region Fields
        private TurretGame game;
        private Model model;
        private int leftFrontLeg;
        private int rightFrontLeg;
        private int leftBackLeg;
        private int rightBackLeg;
        private float legAngel = 0;
        private bool reachedEnd = false;
        Vector3 position;
        Vector3 velocity;
        private Random random = new Random();

        #endregion

        #region Constructor
        public Rat(TurretGame game)
        {
            this.game = game;
        }
        #endregion

        #region LoadContent
        /// <summary>
        /// This function is called to load content into this component
        /// of our game.
        /// </summary>
        /// <param name="content">The content manager to load from.</param>
        public void LoadContent(ContentManager content)
        {
            position = RandomVector(-3000, 3000);
            position.Y = 0;
            velocity = position;
            velocity.Normalize();

            model = content.Load<Model>("Rat-rigid");
            leftFrontLeg = model.Bones.IndexOf(model.Bones["LeftFrontLeg"]);
            rightFrontLeg = model.Bones.IndexOf(model.Bones["RightFrontLeg"]);
            leftBackLeg = model.Bones.IndexOf(model.Bones["LeftBackLeg"]);
            rightBackLeg = model.Bones.IndexOf(model.Bones["RightBackLeg"]);
        }

        #endregion

        #region Update
        /// <summary>
        /// This function is called to update this component of our game
        /// to the current game time.
        /// </summary>
        /// <param name="gameTime"></param>
        public void Update(GameTime gameTime)
        {
            float runSpeed = .06f;        // Seconds

            if (legAngel < 0.30f && !reachedEnd)
            {
                legAngel += (float)(0.20 * gameTime.ElapsedGameTime.TotalSeconds / runSpeed);
                if (legAngel > 0.20f)
                {
                    legAngel = 0.20f;
                    reachedEnd = true;
                }
            }
            else if (legAngel > -0.5f && reachedEnd)
            {
                legAngel -= (float)(0.20 * gameTime.ElapsedGameTime.TotalSeconds / runSpeed);
                reachedEnd = true;
                if (legAngel < -0.2f)
                {
                    legAngel = -0.2f;
                    reachedEnd = false;
                }
            }
        }

        #endregion

        #region Draw
        /// <summary>
        /// This function is called to draw this game component.
        /// </summary>
        /// <param name="graphics"></param>
        /// <param name="gameTime"></param>
        public void Draw(GraphicsDeviceManager graphics, GameTime gameTime)
        {

            double x = position.X;
            double z = position.Z;
            double angle = Math.Atan2(-x, -z);
            DrawModel(graphics, model, Matrix.CreateScale(10) * Matrix.CreateRotationY((float) angle) * Matrix.CreateTranslation( new Vector3((float)x,0,(float)z)));
            position -= 1f * velocity;
        }

        #endregion

        #region DrawModel
        private void DrawModel(GraphicsDeviceManager graphics, Model model, Matrix world)
        {
            Matrix[] transforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(transforms);
            transforms[leftFrontLeg] = Matrix.CreateRotationX(legAngel) * transforms[leftFrontLeg];
            transforms[rightFrontLeg] = Matrix.CreateRotationX(-legAngel) * transforms[rightFrontLeg];
            transforms[leftBackLeg] = Matrix.CreateRotationX(legAngel) * transforms[leftBackLeg];
            transforms[rightBackLeg] = Matrix.CreateRotationX(-legAngel) * transforms[rightBackLeg];

            foreach (ModelMesh lMesh in model.Meshes)
            {
                foreach (BasicEffect lEffect in lMesh.Effects)
                {
                    lEffect.EnableDefaultLighting();
                    lEffect.World = transforms[lMesh.ParentBone.Index] * world;
                    lEffect.View = game.Camera.View;
                    lEffect.Projection = game.Camera.Projection;
                }
                lMesh.Draw();
            }
        }
        #endregion

        #region RandomVector
        private Vector3 RandomVector(float min, float max)
        {
            return new Vector3((float)(min + (random.NextDouble() * (max - min))),
                (float)(min + (random.NextDouble() * (max - min))),
                (float)(min + (random.NextDouble() * (max - min))));
        }
        #endregion

    }
}
